package com.shiguiwu.springboot3.util;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.io.Encoders;
import io.jsonwebtoken.security.Keys;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
@Component
@Data
public class JwtUtils {

    @Value("${jwt.secret:Iv9oOlCkglIlKdfPz0f6XlTNORd0tKvm4ZgeOl5vGVE=}")
    private String secret;

    @Value("${jwt.access.expiration:10000000}")
    private long accessExpiration;

    @Value("${jwt.refresh.expiration:1000000055}")
    private long refreshExpiration;

    public SecretKey getSigningKey() {

        return Keys.hmacShaKeyFor(secret.getBytes(StandardCharsets.UTF_8));
    }

    public static void main(String[] args) {
        // 使用 JJWT 的工具生成一个足够强度的新密钥（用于 HS256 算法）
        SecretKey key = Jwts.SIG.HS256.key().build(); // 这是 0.12.x 版本的新 API
        // 将密钥转换为 Base64 字符串，以便存储在配置文件中
        String secretString = Encoders.BASE64.encode(key.getEncoded());
        System.out.println("Generated Secret Key (BASE64): " + secretString);
    }

    // 生成access_token
    public String generateAccessToken(String username) {
        return buildToken(new HashMap<>(), username, accessExpiration);
    }

    // 生成refresh_token
    public String generateRefreshToken(String username) {
        return buildToken(new HashMap<>(), username, refreshExpiration);
    }

    private String buildToken(Map<String, Object> claims, String subject, long expiration) {
        return Jwts.builder()
                .claims(claims)
                .subject(subject)
                .issuedAt(new Date(System.currentTimeMillis()))
                .expiration(new Date(System.currentTimeMillis() + expiration))
                .signWith(getSigningKey())
                .compact();
    }

    // 从Token中提取用户名
    public String extractToken(String token) {
        return extractClaim(token, Claims::getSubject);
    }


    // 提取Token过期时间
    public Date extractExpiration(String token) {
        return extractClaim(token, Claims::getExpiration);
    }

    public <T> T extractClaim(String token, Function<Claims, T> claimsResolver) {
        final Claims claims = extractAllClaims(token);
        return claimsResolver.apply(claims);
    }

    private Claims extractAllClaims(String token) {
        return Jwts.parser()
                .verifyWith(getSigningKey())
                .build()
                .parseSignedClaims(token)
                .getPayload();
    }

    // 验证Token是否有效
    public boolean validateToken(String token) {
        Jwts.parser()
            .verifyWith(getSigningKey())
            .build()
            .parseSignedClaims(token);
        return true;
    }

    // 检查Token是否过期
    public Boolean isTokenExpired(String token) {
        return extractExpiration(token).before(new Date());
    }
}